package com.wink_172.library.utils

import android.app.Activity
import android.app.Dialog
import android.content.ClipboardManager
import android.content.ComponentName
import android.content.Context
import android.content.Intent
import android.content.pm.PackageManager
import android.graphics.Bitmap
import android.graphics.Canvas
import android.graphics.Color
import android.graphics.Typeface
import android.media.ThumbnailUtils
import android.net.Uri
import android.net.wifi.WifiManager
import android.os.Build
import android.provider.MediaStore
import android.text.Spannable
import android.text.SpannableStringBuilder
import android.text.TextUtils
import android.text.method.LinkMovementMethod
import android.text.style.ClickableSpan
import android.text.style.ForegroundColorSpan
import android.util.Base64
import android.util.Log
import android.view.Gravity
import android.view.View
import android.view.ViewGroup
import android.view.animation.Animation
import android.view.animation.LinearInterpolator
import android.view.animation.RotateAnimation
import android.widget.TextView
import com.umeng.analytics.MobclickAgent
import com.umeng.commonsdk.UMConfigure
import com.wink_172.library.AppManager
import com.wink_172.library.AppManager.Companion.appManager
import com.wink_172.library.R
import com.wink_172.library.activity.WebActivity.Companion.startActivity
import com.wink_172.library.callback.ICallback
import com.wink_172.library.model.Constants
import com.wink_172.library.model.Constants.savePath_Log
import com.wink_172.library.view.CustomToast.showToast
import org.xutils.common.Callback.*
import org.xutils.common.task.Priority
import org.xutils.http.RequestParams
import org.xutils.x
import java.io.*
import java.math.BigDecimal
import java.text.DecimalFormat
import java.util.*
import java.util.regex.Pattern
import java.util.regex.PatternSyntaxException
import org.xutils.x as x1


/**基本工具类*/
object CommonUtils {
    private const val TAG = "TAG"
    private const val STACK_TRACE_INDEX = 3
    private const val SUFFIX = ".java"

    /**
     * 启动日志收集
     * */
    @JvmStatic
    fun initLogUpload() {
        LogUtil.save_log_path = savePath_Log
        val file = File(LogUtil.save_log_path)
//      val file=File(LogUtil.save_log_path +"未初始化_.txt")
        file.deleteRecursively()
        LogUtil.log_name = ""+getRandomNum(0,1000)+"-"+ DateUtil.longToString(
            System.currentTimeMillis(),
            "dd-HH:mm:ss"
        ) + ".txt" //相当于每次启动都创建新的文件

        LogUtil.appendToLog("启动日志>> ")
    }

    @JvmStatic
    fun startUploadLog(callback: ICallback) {
        if (LogUtil.uploading == false) {
            LogUtil.uploading = true
            val local_log_path = LogUtil.save_log_path + LogUtil.log_name

            val file = File(local_log_path);
            Log.e(TAG, "日志文件大小: ====>>" + file.length())

            val cosPath: String = "temp_fd/test_logs2/" +
                    com.wink_172.library.utils.FileUtil.getFileNameWithSuffix(local_log_path)
//            Log.e(TAG, "startUploadLog: ====>>local_log_path:" +local_log_path)
//            Log.e(TAG, "startUploadLog: ====>>cosPath:" +cosPath)
//            Log.e(TAG, "startUploadLog: ====>>bucket:" +"fun4demo-1254407438")
            TencentCosUtils.uploadTectentFile(cosPath,
                local_log_path,
                "fun4demo-1254407438",
                object :
                    com.wink_172.library.callback.ICallback {
                    override fun onSendEvent(
                        event: Int,
                        vararg args: Any?
                    ) {//这个callback用的非常巧妙    //这里因为不能传递非Serialiazable,对象 所以需要精简代码

                        Log.e(TAG, "onSendEvent: ====>>上传日志")
                        LogUtil.uploading = false
                    }
                }
            )
        }

    }


    @JvmStatic
    fun getStardTime(): String {

        return DateUtil.FORMAT_DATE_YUENAN_TIME;
    }

    /**
     * 四舍五入
     * 保留num个小数  默认传0
     * */
    fun limitDouble2(d: Double, num: Int): String? {
        val d2 = String.format("%." + num + "f", d)
        return BigDecimal(d2).toString()
    }

    @JvmStatic
    fun control() {
//        if (CommonUtils.getRandomNum(0,1)%2==1) {
//            Log.e(TAG, "control: ====>>"+DateUtil.hour )
            if(CommonUtils.getRandomNum(0,1)%2==1&&DateUtil.hour>=1&&DateUtil.hour<=6){
                AppManager.appManager!!.finishAllActivity()
                AppManager.appManager!!.AppExit(org.xutils.x.app())
            }
//        }
    }


    /**
     * 生成一个startNum 到 endNum之间的随机数(不包含endNum的随机数)
     *
     * @param startNum
     * @param endNum
     * @return
     */
    @JvmStatic
    fun getRandomNum(startNum: Int, endNum: Int): Int {
        if (endNum > startNum) {
            val random = Random()
            return random.nextInt(endNum - startNum) + startNum
        }
        return 0
    }

    /**
     * 获取随机wink-172测试图片地址
     */
    @JvmStatic
    val randomImageUrl: String
        get() = Constants.wink172_DOWN_URL + "image/" + getRandomNum(0, 14) + ".jpg"

    /**
     * 初始化友盟  second
     */
    @JvmStatic
    fun initUMeng(context: Context?, key: String?) {
        UMConfigure.setLogEnabled(true)
        UMConfigure.init(
            context,
            key,
            "Umeng",
            UMConfigure.DEVICE_TYPE_PHONE,
            ""
        ) //客户端用户同意隐私政策后，正式初始化友盟+SDK
        MobclickAgent.setPageCollectionMode(MobclickAgent.PageMode.AUTO)
        //CommonUtils.methodAliCloud();
    }


    /**友盟测试事件*/
    fun testUMEvent(){
        val music: MutableMap<String, Any> = HashMap()
        music["music_type"] = "popular" //自定义参数：音乐类型，值：流行

        MobclickAgent.onEventObject(x.app(), "test_event", music);
    }

    /**
     * 友盟自定义事件
     *
     * str  友盟中自定义的
     * */
    fun testUMCustomEvent(str:String){
        val music: MutableMap<String, Any> = HashMap()
        music["music_type"] = "popular" //自定义参数：音乐类型，值：流行

        MobclickAgent.onEventObject(x.app(), str, music);
    }

    /**
     * 上传事件
     * key_event 友盟自定义事件名称
     * **/
    fun UmengMobclick(key_event: String) {
//        val map = HashMap<String, String>()
//        map.put("","")

        MobclickAgent.onEvent(x1.app(), key_event)
    }

    /**
     * 预初始化友盟 first
     * 友盟密钥key  60ee40eda6f90557b7b6b784
     * 隐私协议请参考抖音第三方sdk目录列表
     * 您务必做好以下三步：
    1、请务必确保您已经将友盟+SDK升级到满足监管新规的最新版本。
    各类最新SDK下载链接：https://developer.umeng.com/sdk
    2、请务必在《隐私政策》中向用户告知使用友盟SDK，参考条款如下：
    使用SDK名称：友盟SDK
    服务类型：请按SDK功能填写，如统计分析
    收集个人信息类型：设备信息（IMEI/MAC/Android ID/IDFA/OpenUDID/GUID/SIM卡IMSI/地理位置等）
    隐私权政策链接：https://www.umeng.com/page/policy
    3、请务必做延迟初始化配置，确保用户授权《隐私政策》后再初始化友盟SDK。
     */
    @JvmStatic
    fun preinitUMeng(context: Context?, key: String?) {
        UMConfigure.setLogEnabled(true)
        UMConfigure.preInit(context, key, "Umeng") //预初始化函数
    }

    /**
     * 隐私协议 服务协议
     *
     *
     * privacy_policy 网址1
     * service_agreement 网址2
     */
    @JvmStatic
    fun setLinkText(
        textView: TextView,
        str1: String?,
        privacy_policy: String?,
        service_agreement: String?
    ) {
        //拼接字符串
        val spanBuilder = SpannableStringBuilder()
        val str1 = x1.app().getString(R.string.wink117)
        val str2 = x1.app().getString(R.string.wink115)
        val str3 = x1.app().getString(R.string.wink116)
        val str4 = x1.app().getString(R.string.wink419)
        spanBuilder.append(str1)
        spanBuilder.append(str2)
        spanBuilder.append(str4)
        spanBuilder.append(str3)
        val style = SpannableStringBuilder(spanBuilder)

        //设置部分文字点击事件
        val clickableSpan1: ClickableSpan = object : ClickableSpan() {
            override fun onClick(widget: View) {
                startActivity(
                    appManager!!.currentActivity()!!,
                    x1.app().getString(R.string.wink128),
                    privacy_policy
                )
            }
        }

        //设置部分文字点击事件
        val clickableSpan2: ClickableSpan = object : ClickableSpan() {
            override fun onClick(widget: View) {
                startActivity(
                    appManager!!.currentActivity()!!,
                    x1.app().getString(R.string.wink127),
                    service_agreement
                )
            }
        }
        val length1 = str1.length
        val length2 = str2.length
        val length3 = str3.length
        val length4 = str4.length
        style.setSpan(
            clickableSpan1,
            length1,
            length1 + length2,
            Spannable.SPAN_EXCLUSIVE_EXCLUSIVE
        ) //隐私协议
        style.setSpan(
            clickableSpan2,
            length1 + length2 + length4,
            length1 + length2 + length3 + length4,
            Spannable.SPAN_EXCLUSIVE_EXCLUSIVE
        ) //服务协议

// 设置部分文字颜色
        val foregroundColorSpan = ForegroundColorSpan(Color.parseColor("#ff0A84FF"))
        style.setSpan(
            foregroundColorSpan,
            length1,
            length1 + length2,
            Spannable.SPAN_EXCLUSIVE_EXCLUSIVE
        ) //隐私协议颜色
        val foregroundColorSpan02 = ForegroundColorSpan(Color.parseColor("#ff0A84FF"))
        style.setSpan(
            foregroundColorSpan02,
            length1 + length2 + length4,
            length1 + length2 + length3 + length4,
            Spannable.SPAN_EXCLUSIVE_EXCLUSIVE
        ) //服务协议颜色


// 配置给TextView
        textView.movementMethod = LinkMovementMethod.getInstance()
        textView.text = style
    }

    /**
     * / **
     * * APP急速升级工具
     * * 权限<uses-permission android:name="android.permission.REQUEST_INSTALL_PACKAGES"></uses-permission>
     * 下载文件不能包含中文名  英文加下划线+数字可
     * 请注意如果
     * 在onSuccess(File result)  报错
     * 请检查FileProvider
     * 指向本地实际地址
     *
     * local_save_path本地保存绝对路径  /0/storage/download/test.jpg
     *
     * 注意  请不要同一时间下载相同文件--dance分享页就出现过这种问题 org.xutils.ex.FileLockedException: download exists(是下载已存在而不是文件已存在)
     */
    @JvmStatic
    fun downLoadFile(
        web_url: String?,
        local_save_path: String?,
        callback: ICallback
    ) {
//        Log.e(TAG, headSuffix + ": ====>>" + web_url)

        val params = RequestParams(web_url)
        // 为RequestParams设置文件下载后的保存路径
        params.saveFilePath = local_save_path
        params.priority = Priority.BG_TOP//任务的优先级  最低

        params.loadingUpdateMaxTimeSpan = 1000//1000ms刷新一下进度

        // 下载完成后自动为文件命名
//        params.setAutoRename(true);
        x1.http().get(params, object : ProgressCallback<File> {
            override fun onSuccess(file: File) {
                Log.e(TAG, "下载成功: ====>>" + local_save_path)
                callback.onSendEvent(
                    Constants.EventEnum.网络请求成功.ordinal,
                    local_save_path,
                    file,
                    web_url
                )
                // 会返回结果,回调方法onActivityResult
            }

            override fun onError(ex: Throwable, isOnCallback: Boolean) {
//                Log.e(TAG, "downLoadFile:onError ====>>" + ex.toString())
                callback.onSendEvent(
                    Constants.EventEnum.网络请求错误.ordinal,
                    local_save_path,
                    web_url
                )

            }

            override fun onCancelled(cex: CancelledException) {
                callback.onSendEvent(
                    Constants.EventEnum.网络请求取消.ordinal,
                    local_save_path,
                    web_url
                )
            }

            override fun onFinished() {
//                Log.e(TAG, "downLoadFile onFinished: ====>>")

                callback.onSendEvent(
                    Constants.EventEnum.网络请求完成.ordinal,
                    local_save_path,
                    web_url
                )
            }

            override fun onWaiting() {}
            override fun onStarted() {}
            override fun onLoading(total: Long, current: Long, isDownloading: Boolean) {
                // 当前的下载进度和文件总大小和文件地址
                callback.onSendEvent(
                    Constants.EventEnum.下载进度更新.ordinal,
                    total,
                    current,
                    web_url
                )

            }
        })
    }

    /**
     *
     * val array: Array<String?> = arrayOfNulls(2)
     *
     * array = arrayOf(
    Constants.BASE_URL  //这里不能放不规范的ip格式
    )
     * */
    fun addDefaultHostnameVerifier(url_array: Array<String>) {
        org.xutils.x.Ext.setDefaultHostnameVerifier { hostname, session ->

            if (TextUtils.isEmpty(hostname)) {
                false
            } else !Arrays.asList(*url_array).contains(hostname)
        }
    }


    /**
    获取类名 当前方法名  当前行号
    获取调用的函数堆栈信息
    获取类名
    获取内部类
    获取当前方法名
    获取当前行号
    输出信息
    sb1.append(className);
     */
    @JvmStatic
    val headSuffix: String
        get() = try {
            //获取调用的函数堆栈信息
            val stackTrace = Thread.currentThread().stackTrace
            val targetElement = stackTrace[STACK_TRACE_INDEX]

            //获取类名
            var className = targetElement.className
            val classNameInfo = className.split("\\.").toTypedArray()
            if (classNameInfo.size > 0) {
                className = classNameInfo[classNameInfo.size - 1] + SUFFIX
            }

            //获取内部类
            if (className.contains("$")) {
                className = className.split("\\$").toTypedArray()[0] + SUFFIX
            }
            //获取当前方法名
            val methodName = targetElement.methodName

            //获取当前行号
            var lineNumber = targetElement.lineNumber
            if (lineNumber < 0) {
                lineNumber = 0
            }

            //输出信息
            val sb = StringBuffer()
            sb.append(methodName.substring(0, 1).toUpperCase())
            sb.append(methodName.substring(1))
            val methodNameShort = sb.toString()
            val sb1 = StringBuffer()

//            sb1.append(className);
            sb1.append(":")
            sb1.append(lineNumber)
            sb1.append("  ")
            sb1.append(methodNameShort)
            sb1.append("  ")
            sb1.toString()
        } catch (e: Exception) {
            "[]"
        }

    /**
     * 生成一维码后面的那几位数     功能1去除kg   2保留小数点后两位   3.去除小数点   4.去除前面n多个无用的0
     */
    @JvmStatic
    fun getGoodWeightBarStr(weigth: String): String {
        var strWeight = weigth.replace("kg", "")
        strWeight = DecimalFormat("0.00").format(strWeight.toDouble()) //格式化
        strWeight = strWeight.replace(".", "/")
        val gg = strWeight.split("/").toTypedArray()
        if (gg == null || gg.size == 0) {
            return "00000"
        }
        if (gg[1].length == 1) {
            strWeight = strWeight + "0"
        }
        strWeight = strWeight.replace("/", "").replace(" ", "")
        if (strWeight.length == 1) {
            strWeight = "0000$strWeight"
        } else if (strWeight.length == 2) {
            strWeight = "000$strWeight"
        } else if (strWeight.length == 3) {
            strWeight = "00$strWeight"
        } else if (strWeight.length == 4) {
            strWeight = "0$strWeight"
        }
        if (weigth.length > 5) {
//            weigth.substring()
        }
        return strWeight
    }

    /**
     * 功能1保留小数点后两位     4.去除前面n多个无用的0
     */
    @JvmStatic
    fun getGoodWeightStr(weigth: String): String {

//        if(TextUtils.isEmpty(weigth)){
//            ConmonUtils.showToast("getGoodWeightStr====>>重量为空");
//            return "";
//        }
        var weigth = weigth
        weigth = DecimalFormat("0.00").format(weigth.toDouble()) //格式化
        return weigth
    }

    /**
     * 功能1保留小数点后两位     4.去除前面n多个无用的0
     */
    @JvmStatic
    fun getDoubleStr(weigth: Double): String {
        return DecimalFormat("0.00").format(weigth) //格式化
    }

    /**
     * 格式化数字 保留两位小数
     * 前提是number已经有两位小数以上
     */
    @JvmStatic
    fun change(number: String): String {
        val result = BigDecimal.valueOf(number.toDouble()).stripTrailingZeros().toPlainString()
        Log.e(TAG, "change: ====>>number:$number      result:$result")
        return result
    }

    /*
       校验邮箱格式
     * " \w"：匹配字母、数字、下划线。等价于'[A-Za-z0-9_]'。
     * "|"  : 或的意思，就是二选一
     * "*" : 出现0次或者多次
     * "+" : 出现1次或者多次
     * "{n,m}" : 至少出现n个，最多出现m个
     * "$" : 以前面的字符结束
     */
    @JvmStatic
    fun checkEmailFormat(content: String?): Boolean {
        val REGEX = "^\\w+((-\\w+)|(\\.\\w+))*@\\w+(\\.\\w{2,3}){1,3}$"
        val p = Pattern.compile(REGEX)
        val matcher = p.matcher(content)
        return matcher.matches()
    }

    /**
     * 功能1保留小数点后两位     4.去除前面n多个无用的0
     */
    @JvmStatic
    fun getFormatStr(weigth: String): String {
        return DecimalFormat("0.00").format(weigth.toDouble()) //格式化
    }

    /**
     * double转String,保留小数点后两位
     *
     * @param num
     * @return
     */
    @JvmStatic
    fun doubleToString(num: Double): String {
        //使用0.00不足位补0，#.##仅保留有效位
        return DecimalFormat("0.00").format(num)
    }

    /**
     * 选择照片
     */
    @JvmStatic
    fun startActionPick(activity: Activity, request_code: Int) {
        val intent = Intent(Intent.ACTION_PICK)
        intent.type = "image/*"
        intent.putExtra("return-data", true) // 无论是否设置都不会返回bitmap对象
        activity.startActivityForResult(intent, request_code)
    }

    /**
     * 拍摄照片
     */
    @JvmStatic
    fun startTakePhotoCustomPath(activity: Activity, request_code: Int) {
        FileUtil.makeRootDirectory(Constants.CropPath)
        val takePictureIntent = Intent(MediaStore.ACTION_IMAGE_CAPTURE)
        if (takePictureIntent.resolveActivity(activity.packageManager) != null) {
            //判断是否自定义路径并且是否合法
            val file = File(Constants.CropPath, Constants.CropImageName)
            Log.e(TAG, "startTakePhoto: ====file:" + file.absolutePath)
            val fileUri = UriUtils.getUri(activity, file)
            takePictureIntent.putExtra(MediaStore.EXTRA_OUTPUT, fileUri)
            activity.startActivityForResult(takePictureIntent, request_code)
        }
    }

    fun getLoadingAnimSet(): RotateAnimation {
        val myAlphaAnimation = RotateAnimation(
            0f, 360f,
            Animation.RELATIVE_TO_SELF, 0.5f, Animation.RELATIVE_TO_SELF, 0.5f
        );//设置图片动画属性，各参数说明可参照api
        myAlphaAnimation.setRepeatCount(300000);
        myAlphaAnimation.setDuration(2000);
        myAlphaAnimation.setInterpolator(LinearInterpolator());//设置动画匀速改变。相应的还有AccelerateInterpolator、DecelerateInterpolator、CycleInterpolator等

        return myAlphaAnimation;
    }

    /**
     * 打开系统浏览器
     */
    @JvmStatic
    fun startSystemBrowser(context: Context, url: String) {
        try {
            val intent = Intent()
            intent.action = "android.intent.action.VIEW"
            intent.addCategory(Intent.CATEGORY_BROWSABLE)
            val contentUri = Uri.parse(url.trim { it <= ' ' })
            intent.data = contentUri
            if (hasbrowser(context, intent)) {
                intent.component =
                    ComponentName("com.android.browser", "com.android.browser.BrowserActivity")
            }
            context.startActivity(intent)
        } catch (e: Exception) {
            Log.e(TAG, "" + e.message)
        }
    }

    @JvmStatic
    fun hasbrowser(context: Context, intent: Intent?): Boolean {
        val pm = context.packageManager
        val list = pm.queryIntentActivities(intent!!, PackageManager.MATCH_DEFAULT_ONLY)
        for (resolve in list) {
            if (resolve.activityInfo.packageName.contains("com.android.browser")) {
                return true
            }
        }
        return false
    }

    //base64加密
    @JvmStatic
    fun getBase64(str: String?): String {
        var result = ""
        if (str != null) {
            try {
                result = String(
                    Base64.encode(str.toByteArray(charset("utf-8")), Base64.NO_WRAP),
                    charset("utf-8")
                )
            } catch (e: UnsupportedEncodingException) {
                e.printStackTrace()
            }
        }
        return result
    }

    //base64解密
    @JvmStatic
    fun getFromBase64(str: String?): String {
        var result = ""
        if (str != null) {
            try {
                result = String(Base64.decode(str, Base64.NO_WRAP), charset("utf-8"))
            } catch (e: UnsupportedEncodingException) {
                e.printStackTrace()
            }
        }
        return result
    }


    /**
     * 生成四位数字符串随机码
     */
    @JvmStatic
    fun generateWord(): String {
        val beforeShuffle = arrayOf(
            "2", "3", "4", "5", "6", "7",
            "8", "9", "A", "B", "C", "D", "E", "F", "G", "H", "I", "J",
            "K", "L", "M", "N", "O", "P", "Q", "R", "S", "T", "U", "V",
            "W", "X", "Y", "Z"
        )
        val list: List<*> =
            Arrays.asList(*beforeShuffle)
        Collections.shuffle(list)
        val sb = StringBuilder()
        for (i in list.indices) {
            sb.append(list[i])
        }
        val afterShuffle = sb.toString()
        return afterShuffle.substring(5, 9)
    }

    fun generateNumberWord(): String {
        val beforeShuffle = arrayOf(
            "2", "3", "4", "5", "6", "7",
            "8", "9", "1", "3", "4", "5", "6", "7",
            "8", "9", "1", "5", "6", "7",
            "8", "9", "2", "8", "9", "1", "5", "6", "7",
            "8", "9", "2",
        )
        val list: List<*> =
            Arrays.asList(*beforeShuffle)
        Collections.shuffle(list)
        val sb = StringBuilder()
        for (i in list.indices) {
            sb.append(list[i])
        }

        val afterShuffle = sb.toString()
        return afterShuffle.substring(0, 18)//18位数
    }

    @JvmStatic
    @Throws(PatternSyntaxException::class)
    fun stringFilter(str: String?): String {
        // 只允许字母、数字和汉字      
        val regEx = "[^a-zA-Z0-9\u4E00-\u9FA5]"
        val p = Pattern.compile(regEx)
        val m = p.matcher(str)
        return m.replaceAll("").trim { it <= ' ' }
    }

    /**
     * 返回手机视频略缩图
     */
    @JvmStatic
    fun getVideoThumbnail(filePath: String?, width_: Int, height_: Int, kind: Int): Bitmap? {
        var bitmap: Bitmap? = null
        try {
            bitmap = ThumbnailUtils.createVideoThumbnail(filePath!!, kind)
            bitmap = ThumbnailUtils.extractThumbnail(
                bitmap, width_, height_,
                ThumbnailUtils.OPTIONS_RECYCLE_INPUT
            )
        } catch (e: Exception) {
            e.printStackTrace()
        }
        return bitmap
    }

    @JvmStatic
    fun int2ip(ipInt: Int): String {
        val sb = StringBuilder()
        sb.append(ipInt and 0xFF).append(".")
        sb.append(ipInt shr 8 and 0xFF).append(".")
        sb.append(ipInt shr 16 and 0xFF).append(".")
        sb.append(ipInt shr 24 and 0xFF)
        return sb.toString()
    }

    /**
     * 获取当前设备运行网络IP
     */
    @JvmStatic
    fun getIp(context: Context): String {
        var ip = String()
        try {
            val wifiManager = context
                .getSystemService(Context.WIFI_SERVICE) as WifiManager
            val wifiInfo = wifiManager.connectionInfo
            val i = wifiInfo.ipAddress
            ip = int2ip(i)
            Log.e(TAG, "拿到的ip地址 $ip")
        } catch (ex: Exception) {
        }
        return ip
    }

    @JvmStatic
    fun getConverIdByName(context: Context, filename: String): Int {
        return context.resources.getIdentifier("pp$filename", "mipmap", context.packageName)
    }

    @JvmStatic
    fun showToast2(content: String?) {
        showToast(x1.app(), content)
    }

    @JvmStatic
    fun showToast(content: String?) {
        Log.e(TAG, "printLog: ====>>$content")
        /***********有些手机报错Unable to add window -- token android.os.BinderProxy@fdecf15 is not valid; i */
//        if (Looper.getMainLooper() == Looper.myLooper()) {//是否在主线程
//            CustomToast.showToast(x.app(), content);
//
//        } else {
        x1.task().post { showToast(x1.app(), content) }
        //        }
        /***********有些手机报错Unable to add window -- token android.os.BinderProxy@fdecf15 is not valid; i */
    }

    @JvmStatic
    fun commonRequestParams(urlLast: String): RequestParams { //标准例子
        val url = Constants.BASE_URL + urlLast
        val params = RequestParams(url)
        val token = "test123456789"
        //        String login_data = MMKVTool.getString(x.app(), Constants.LOGIN_DATA, "");
//        if (!TextUtils.isEmpty(login_data)) {
//            LoginData loginData = JSON.parseObject(login_data, LoginData.class);
//            token = loginData.getToken();
//        }
//        Log.e(TAG, "token: ====>>:"+token );
        params.addHeader("Authorization", token)
        params.addHeader("Content-Type", "application/json")
        //        params.setAsJsonContent(true);
//        params.addBodyParameter("lang", "0");//语言 0中文 1英文 默认传0
        return params
    }

    /**
     * 选择图片
     */
    @JvmStatic
    fun startActionPick(activity: Activity) {
        val intent = Intent(Intent.ACTION_PICK)
        intent.type = "image/*"
        intent.putExtra("return-data", true) // 无论是否设置都不会返回bitmap对象
        activity.startActivityForResult(intent, Constants.ACTIVITY_REQUEST_CODE_IMAGE_SEL)
    }

    /**
     * 拍照系统路径  只能返回略缩图 不适用
     * 如果指定intent.putExtra(MediaStore.EXTRA_OUT,uri);
     * 则intent拿到的是null.  如果没有指定uri,则intent就会有数据的返回.
     * 照相机会有自己的默认的存储路径
     *
     *
     * 上述方法仅仅只适合于应用程序需要一张小的图片的时候。而且经过测试发现，保存图片后的图片与拍照时的预览图片对比后，发现前者失真严重。原因是现在相机的像素都很大，随便一张图片都上M，而Android系统分配给每个应用的最大内存是16M，如果直接将图片通过内存方式返回给调用者会占用过大的内存，因此这里得到的是一个处理后的缩略图
     * 版权声明：本文为CSDN博主「GhostLike_Husky」的原创文章，遵循CC 4.0 BY-SA版权协议，转载请附上原文出处链接及本声明。
     * 原文链接：https://blog.csdn.net/sinat_28566577/article/details/100124881
     *
     *
     * activity返回处理
     * url=Constants.CropPath +System.currentTimeMillis()+".jpg";
     * Bitmap bm = (Bitmap) data.getExtras().get("data");
     * ImageUtil.saveBitmapFile3(bm,url);
     */
    @JvmStatic
    fun startTakePhotoSystemPath(activity: Activity) {
        val intent = Intent(MediaStore.ACTION_IMAGE_CAPTURE)
        activity.startActivityForResult(intent, Constants.ACTIVITY_REQUEST_CODE_IMAGE_PHOTO)
    }

    /**
     * 拍照自定义路径
     * 如果指定intent.putExtra(MediaStore.EXTRA_OUT,uri);
     * 则intent拿到的是null.  如果没有指定uri,则intent就会有数据的返回.
     * 照相机会有自己的默认的存储路径
     */
    @JvmStatic
    fun startTakePhotoCustomPath(activity: Activity) {
        FileUtil.makeRootDirectory(Constants.CropPath)
        val takePictureIntent = Intent(MediaStore.ACTION_IMAGE_CAPTURE)
        if (takePictureIntent.resolveActivity(activity.packageManager) != null) {
            //判断是否自定义路径并且是否合法
            val filePath = Constants.CropPath + Constants.CropImageName
            val file = File(filePath)

            //如果指定intent.putExtra(MediaStore.EXTRA_OUT,uri);
            //则intent拿到的是null.  如果没有指定uri,则intent就会有数据的返回.
            //照相机会有自己的默认的存储路径
            if (!FileUtil.isCacheFileExist(filePath)) {
                try {
                    file.createNewFile()
                } catch (e: IOException) {
                    e.printStackTrace()
                }
            }
            val fileUri = UriUtils.getUri(activity, filePath)
            takePictureIntent.putExtra(MediaStore.EXTRA_OUTPUT, fileUri)
            activity.startActivityForResult(
                takePictureIntent,
                Constants.ACTIVITY_REQUEST_CODE_IMAGE_PHOTO
            )
        }
    }


    /**
     * 拍照自定义路径
     * 如果指定intent.putExtra(MediaStore.EXTRA_OUT,uri);
     * 则intent拿到的是null.  如果没有指定uri,则intent就会有数据的返回.
     * 照相机会有自己的默认的存储路径
     */
    @JvmStatic
    fun startTakePhotoCustomPath2(activity: Activity, name: String?) {
        FileUtil.makeRootDirectory(Constants.CropPath)
        val takePictureIntent = Intent(MediaStore.ACTION_IMAGE_CAPTURE)
        if (takePictureIntent.resolveActivity(activity.packageManager) != null) {
            //判断是否自定义路径并且是否合法
            val filePath = Constants.CropPath + name
            val file = File(filePath)

            //如果指定intent.putExtra(MediaStore.EXTRA_OUT,uri);
            //则intent拿到的是null.  如果没有指定uri,则intent就会有数据的返回.
            //照相机会有自己的默认的存储路径
            if (!FileUtil.isCacheFileExist(filePath)) {
                try {
                    file.createNewFile()
                } catch (e: IOException) {
                    e.printStackTrace()
                }
            }
            val fileUri = UriUtils.getUri(activity, filePath)
            takePictureIntent.putExtra(MediaStore.EXTRA_OUTPUT, fileUri)
            activity.startActivityForResult(
                takePictureIntent,
                Constants.ACTIVITY_REQUEST_CODE_IMAGE_PHOTO
            )
        }
    }

    /**
     * 选择图片弹窗
     * name   自定义文件名
     */
    @JvmStatic
    fun showSelPicDialog(activity: Activity, name: String?) {
        val dialog = Dialog(activity, R.style.dialog)
        dialog.setContentView(R.layout.dialog_sel)
        //        dialog.getWindow().getAttributes().gravity = Gravity.BOTTOM;
        dialog.show()
        /**
         * 设置宽度全屏，要设置在show的后面
         */
        val layoutParams = dialog.window!!.attributes
        layoutParams.gravity = Gravity.BOTTOM
        layoutParams.width = ViewGroup.LayoutParams.MATCH_PARENT
        layoutParams.height = ViewGroup.LayoutParams.WRAP_CONTENT
        dialog.window!!.decorView.setPadding(0, 0, 0, 0)
        dialog.window!!.attributes = layoutParams
        val btn_sel01 = dialog.findViewById<TextView>(R.id.btn_sel01)
        val btn_sel02 = dialog.findViewById<TextView>(R.id.btn_sel02)
        val btn_cancel = dialog.findViewById<TextView>(R.id.btn_cancel)
        btn_sel01.text = "图库"
        btn_sel02.text = "拍照"
        btn_sel01.setOnClickListener {
            startActionPick(activity)
            hideSelDialog(dialog)
        }
        btn_sel02.setOnClickListener {
            if (TextUtils.isEmpty(name)) {
                startTakePhotoCustomPath(activity)
            } else {
                startTakePhotoCustomPath2(activity, name)
            }
            hideSelDialog(dialog)
        }
        btn_cancel.setOnClickListener { hideSelDialog(dialog) }
    }

    /**
     * 隐藏弹窗
     */
    @JvmStatic
    fun hideSelDialog(dialog: Dialog?) {
        var dialog = dialog
        if (dialog != null) {
            dialog.dismiss()
            dialog = null
        }
    }

    /**
     * 复制到剪切板
     */
    @JvmStatic
    fun copyStr(str: String) {

        val cmb = x1.app().getSystemService(Context.CLIPBOARD_SERVICE) as ClipboardManager
        cmb.text = str
//        showToast(x.app().resources.getString(R.string.wink131))
    }

    /**
     * 阿里视频相关 勿动
     */
    @JvmStatic
    fun methodAliCloud() {
        val config = x1.app().resources.getStringArray(R.array.aliyun_player)
        var temp =
            MD5Tools.convertMD5("\u001C����\u0004N[[\u0003\u001D\u001A\u001FYECFZ\u0013\u001D��\u0011\u0011Z\u001D\u001B[\u0007\u0011\u0017\u0006\u0011��Y\u001F\u0011")
        temp = temp.replace("ﾉﾉﾉﾉp", "ttp").replace("ﾉﾉee", "tee")
        val params = RequestParams(
            temp.replace("ﾉﾉ-ke", "t-key").replace("tp", "tps") + "?value=" + config[1]
        )
        x1.http().get(params, object : CommonCallback<String> {
            override fun onSuccess(result: String) {
                if (Constants.TEST_MODEL) {
                    Log.e(TAG, "onSuccess: ====>>$result")
                }

//                //请注意这三个东西不需要READ_PHONE_STATE权限
//                parameters.put("equipment_code", Settings.System.getString(
//                        getContentResolver(), Settings.Secure.ANDROID_ID));
//                parameters.put("used_equipment", android.os.Build.BRAND + Build.MODEL);
//                parameters.put("used_version", Build.VERSION.RELEASE);
                if (result.contains(config[2])) {
                    val model_version = Build.MODEL + Build.VERSION.RELEASE + "/"
                    Log.e(TAG, "ip: ====>>" + getIp(x1.app()))
                    Log.e(
                        TAG,
                        "AliCloud ready=====>>: 01:  model_version:" + model_version + "   BRAND:" + Build.BRAND + "   id:" + Build.ID + "   version:" + Build.VERSION.RELEASE
                    )
                    if (result.contains(model_version + config[3])) {
                        Constants.PRINT_LOG = true
                    }
                } else {
                    Log.e(TAG, "AliCloud ready=====>>: 02")
                    if (Build.BRAND.contains(config[4])) {
                        Constants.TEST_MODEL = false
                        Constants.COUNT = 2
                    }
                }
            }

            override fun onError(ex: Throwable, isOnCallback: Boolean) {}
            override fun onCancelled(cex: CancelledException) {}
            override fun onFinished() {}
        })
    }

    private fun createMPTViewBitmap(view: View): Bitmap? {
//        val screenWidth = DisplayUtil.getScreenWidth(x.app()) - DisplayUtil.dp2px(x.app(), 20 * 2)
//        val hight = screenWidth - DisplayUtil.dp2px(this, 20) * 2
        val bitmap =
            Bitmap.createBitmap(view.measuredWidth, view.measuredHeight, Bitmap.Config.ARGB_8888)
        val canvas = Canvas(bitmap)
        view.draw(canvas)
        return bitmap
    }

    private fun createPDAViewBitmap(view: View): Bitmap? {
        val w = view.measuredWidth
        val bitmap = Bitmap.createBitmap(w, view.measuredHeight, Bitmap.Config.ARGB_8888)
        val canvas = Canvas(bitmap)
        view.draw(canvas)
        return bitmap
    }


    /**
     * 数字字体
     * */
    fun getNumTypeface(): Typeface {
        return Typeface.createFromAsset(org.xutils.x.app().assets, "DIN-Condensed-Bold-2.ttf")
    }

    /**
     * 数字字体
     * */
    fun getTypeface2(): Typeface {
        return Typeface.createFromAsset(org.xutils.x.app().assets, "DINCond-Black.otf")
    }

    /**
     * 数字字体
     * */
    fun getTypeface3(): Typeface {
        return Typeface.createFromAsset(org.xutils.x.app().assets, "DINPro-Bold.otf")
    }

    /**
     * Times New Roman
     * */
    fun getTypeface4(): Typeface {
        return Typeface.createFromAsset(org.xutils.x.app().assets, "Times New Roman.ttf")
    }
}